# -*- encoding:utf8 -*-
from django.http import HttpResponse
import view_layer
import tool_func
import leave
import attend
from convert import i2h, i2day,date2str,str2date,str2dt,dt2str,t2day,day2t
from login import get_user
from tool_func import get_or_none
from models import LeaveApplication,AttendReport,MsgModel,AttendRecord,AvaiLeave
from datetime import datetime,timedelta
# from leave import subleave_span,apply_chain,revoke_leave
from django.utils import timezone
import weixin
from staff.models import StaffInfo

def get_global():
    return globals()

def log_staff(func):
    @tool_func.require_request
    def _func(request,**kw):
        if 'staff' not in kw:
            staff = get_user(request)
        else:  
            staff = kw.pop('staff')  # 如果包装的函数自带staff，就用函数自带的staff
        if not staff:
            return {'status':'fail','msg':'you are not employee'}
            # dc = weixin.auth_url()  # 微信auth地址的前后坠，客户端只需要把自己的url嵌入到里面，就能获取到code值
            # dc.update({'status': 'not_login', 'msg': 'you need login'})
            # return dc
        else:
            return func(staff=staff,**kw)
    return _func

@log_staff
def revoke_leave(staff, leaveid):
    """
    员工自己撤销自己的请假，当状态是pending时
    """
    app = get_or_none(LeaveApplication, id=leaveid, staff=staff)
    if app and app.status=='pending':
        app.status='revoked'
        app.save()
        # leave.revoke_application(app)
        return {'status': 'success'}
    else:
        return {'status': 'error', 'msg': 'leave not exist'}    

@log_staff
def submit_leave(staff, category, start_time, end_time, reason):
    start_time=dt2str(str2dt(start_time))
    end_time=dt2str(str2dt(end_time))
    try:
        leave.submit_leave(staff, category, start_time, end_time, reason)
        return  {'status':'success'}
    except UserWarning as e:
        return e.args[0]

@log_staff
def get_annual_left(staff):
    """
    获取员工年假剩余
    """
    # leave.update_annual(staff)
    dc = {
        'status': 'success',
        'this_left': i2day(leave.annual_left_this(staff)),
        'last_left': i2day(leave.annual_left_last(staff))
    }
    return dc


@log_staff
def get_swap_left(staff):
    """
    """
    left = leave.swapoff_left(staff)
    dc = {
        'status': 'success',
        'swap_left': i2h(left)
    }
    return dc

@log_staff
def this_month_leave_report(staff):
    """
    获取员工的请假记录 (微信)
    """
    now=datetime.now()
    firstday = date2str(now.date().replace(day=1))
    finalday= date2str( now.replace(month=now.month+1,day=1)-timedelta(days=1))
    attend.report(staff,finalday)
    report=get_or_none(AttendReport,staff=staff,start_date=firstday)
    if report:
        return {
            'personal':report.person_leave,
            'sick':report.sick,
            'annual':report.annual,
            'other':report.other_paid_leave,
            'swap_off':report.swap_off
        }
    else:
        return {}
    
@log_staff
def leave_record_90(staff):
    """
    某员工，90天内的请假记录
    """
    now=datetime.now().date()
    day90_ago=date2str(now-timedelta(days=90))+' 00:00'
    leaves=[]
    for l in LeaveApplication.objects.filter(staff=staff,create_time__gte=day90_ago):
        date= date2str( str2dt(l.start_time).date())
        span=leave.application_leave_span(l)
        if l.category=='swap_off':
            span=i2h(span)
        else:
            span=i2day(span)
        leaves.append({'id':l.id,
                       'status':l.status,
                       'date':date,
                       'category':l.category,
                       'span':span,
                       'detail_url':'leave_detail.html#/?id=%s'%l.id
                        })
    return {'leaves':leaves}

@log_staff
def current_user(staff):
    return {'cn_name':staff.cn_name,'en_name':staff.en_name,'empid':staff.employee_id}

@log_staff
def leave_detail(staff,leave_id):
    """
    微信中显示leave的详情
    """

    leave_row=get_or_none(LeaveApplication,id=leave_id,staff=staff)
    if not leave_row:
        return {'status':'fail','msg':'the leave[id=%s] that you query is not belong to you'%leave_id}
    return {'status':'success','leave':leave.dictfy(leave_row)}
   

@log_staff
def leave_query(staff):
    """
    剩余假期查询。(微信端)
    """
    annual_base=leave.annual_base(staff)
    annual_accum= leave.annual_accum(staff)
    annual_left_this=leave.annual_left_this(staff)
    annual_left_last=leave.annual_left_last(staff)
    total_left=leave.annual_left(staff)
    #leave_dc={
        #'annual_left':{'value':i2day(total_left),'unit':'day'},
        #'annual_base':annual_base,
        #'this_annual_accum':i2day(annual_accum),
        #'last_annual_left':i2day(annual_left_last),
        #'used_annual':i2day(leave.annual_used_this(staff)),
        #'swap_left': i2h(leave.swapoff_left(staff))
    #}    
    leave_dc={
        'annual_left':{'value':i2day(total_left),'unit':'day'},
        'annual_base':{'value':annual_base,'unit':'day'},
        'annual_accum':{'value':i2day(annual_accum),'unit':'day'},
        'annual_left_last':{'value':i2day(annual_left_last),'unit':'day'},
        'annual_used_this':{'value':i2day(leave.annual_used_this(staff)),'unit':'day'},
        'swapoff_left': {'value':i2h(leave.swapoff_left(staff)),'unit':'hour'}
    }
    return leave_dc


@log_staff
def approval_history(staff):
    """
    领导审批的历史
    """
    history=[]
    now=timezone.now().date()
    thirty_day_ago=now-timedelta(days=30)
    start_date_str= date2str(thirty_day_ago)
    for msg in MsgModel.objects.filter(staff=staff, gen_time__gte=start_date_str,category__startswith='check'):
        history.append({'approve_url':'approve.html#/?id=%s'%msg.id,
                        'gen_time':msg.gen_time,
                        'status':msg.status,
                        'title':msg.title})
    return history


@log_staff
def leave_check_msg_detail(staff,msg_id):
    """
    获取审批详情
    """
    msg=get_or_none(MsgModel,staff=staff,id=msg_id,category__startswith='check')
    if not msg:
        return {'status':'fail','msg':'the message not belong to you or not leave check message'}
    leave_row=get_or_none(LeaveApplication,id=msg.content)
    if not leave_row:
        msg.delete()
        return  {'status':'fail','msg':'the related leave not exist'}
    if leave_row.status=='revoked':
        msg.status='revoked'
        msg.save()
        return  {'status':'fail','msg':'the related leave is revoked'}
    # if msg.category=='leave_check_func':
        # note=leave_row.func_leader_note
    # elif msg.category=='leave_check_pro':
        # note=leave_row.pro_leader_note
    # elif msg.category=='leave_check_super':
        # note=leave_row.super_leader_note
    # else:
        # note='msg category has error,the Note you get may be wrong'
    leave_detail=leave.dictfy(leave_row)
    leave_detail['span']=i2day(leave_detail['span'])
    msg_dc={
        # 'category':msg.category,
        'id':msg.id,
        'status':msg.status}
    return {'status':'success','leave_detail':leave_detail,'msg_info':msg_dc}


@log_staff
def process_msg(staff,msg_id,status):
    msg = get_or_none(MsgModel, id=msg_id, staff=staff)
    if not msg:
        return {'status': 'error', 'msg': 'not valid msg'}
    msg.status = status
    msg.save()
    return {'status': 'success'}


@log_staff
def approve_leave(staff,leave_id,check,note):
    """
    领导审批假期
    @type staff:StaffInfo ,领导
    @type leave_id:str,假期的ID
    @type check:str,领导审批后的状态
    @type note:str,领导审批的评语
    """
    return leave.check_leave_app(staff.employee_id, leave_id, check, note)
  

@log_staff
def attendance_report(staff,year_month=None):
    """员工在微信端查询自己的最新的已经统计了的考勤
    """
    if year_month is None:
        now=datetime.now()
        year_month="%s-%02d"%(now.year,now.month)
    report=get_or_none(AttendReport,staff=staff,start_date__startswith=year_month)
    if not report:
        return {'status':'fail','msg':'have not valid attendance record'}
    report_dc={'ymonth':year_month,
        'personal_leave': {'value':report.person_leave,'unit':'day'},
        'start_date':{'value':report.start_date,'unit':'date'},
        'due_date':{'value':report.due_date,'unit':'date'},
        'sick_leave':{'value':report.sick,'unit':'day'},
        'other_paid_leave':{'value':report.other_paid_leave,'unit':'day'},
        'paid':{'value':report.paid_leave,'unit':'day'},
        'miss_check':{'value':report.miss_check,'unit':'times'},
        'late1':{'value':report.late1,'unit':'times'},
        'late2':{'value':report.late2,'unit':'times'},
        'late3':{'value':report.late3,'unit':'times'},
        'late4':{'value':report.late4,'unit':'times'},
        'absent':{'value':report.absent,'unit':'day'},
        'full_attend':{'value':report.full_attend,'unit':'bool'},
        'deduction':{'value':report.deduction_day,'unit':'day'},
        'process':{'value':report.process,'unit':'text'}

    }
    return {'status':'success','report':report_dc}

@log_staff
def attend_record(staff,start_date=None,end_date=None,keyword=None,workday=None,restday=None):
    """
    staff:用于验证是否有权限,例如Hr
    """
    out=attend.attend_record(start_date,end_date,keyword,workday,restday)
    
    return {'records':out}


@log_staff
def hr_leave_record(staff,start_date=None,end_date=None,keyword=None):
    """
    staff:指Hr
    """
    leaves=leave.filter_leave_app(start_date, end_date, keyword)
    return {'status':'success','leaves':leaves}

@log_staff
def hr_attend_report(staff,start_date=None,due_date=None,keyword=None):
    """
    """
    reports=attend.attend_report(start_date, due_date, keyword)
    return {'status':'success','reports':reports}

@log_staff
def hr_check(staff,start_date=None,end_date=None):
    dc={'category__in':['miss_check',]
    }
    
    if start_date:
        dc['start_time__gte']=start_date+' 06:00'
        if end_date:
            dc['end_time__lte']=end_date+' 23:30'
    else:
        monthfirst=date2str(timezone.now().date().replace(day=1))
        dc['start_time__gte']=monthfirst
            
    out=[]
    for row in LeaveApplication.objects.filter(**dc):
        out.append(leave.dictfy_application(row))
    return {'status':'success','records':out}


@log_staff
def update_application(staff,records):
    """
    g更新列表
    """
    out=[]
    for app in records:
        rt=leave.update_leave_application(app)
        if rt:
            out.append(leave.dictfy(rt))
    # app_dc=leave.dictfy_application(row)
    return {'status':'success','records':out}


@log_staff
def get_staff_list(staff):
    ls=[]
    for emp in StaffInfo.objects.all():
        ls.append({'empid':emp.employee_id,'name':emp.cn_name})
    return {'status':'success','stafflist':ls}


# @log_staff
# def get_avai_leave(staff,empid):
    # ls=[]
    # emp=get_or_none(StaffInfo,employee_id=empid)
    # if emp:
        # leave.update_annual(emp)
    # else:
        # return {'status':'fail','msg':'not employee id'}
    # for row in AvaiLeave.objects.filter(staff=emp):
        # ls.append({'id':row.id,
                   # 'category':row.category,
                   # 'span':row.span,
                   # 'used':row.used,
                   # 'start_date':row.start_date,
                   # 'is_valid':row.is_valid,
                   # 'note':row.note})
    # return {'status':'success','records':ls}

@log_staff
def filter_avai_leave(staff,start_date=None,end_date=None,category=None,keyword=None,only_valid=None):
    records=leave.filter_avai_leave(start_date,end_date, keyword=keyword,only_valid=only_valid)
    #for row in records:
        #row['span']=t2day(row['span'])
    return {'status':'success','records':records}


@log_staff
def update_availeaves(staff,records):
    out=[]
    for r in records:
        #r['span']=day2t(r['span'])
        out.append(leave.update_availeave(r))
    rt_records=[leave.dictfy(avai) for avai in out]
    #for row in rt_records:
        #row['span']=t2day(r['span'])
    return {'status':'success','records':rt_records}

# @log_staff
# def get_excel(staff,data):

@log_staff
def refresh_annual(staff):
    for staff in StaffInfo.objects.all():
        leave.update_annual(staff)
    return {'status':'success'}


@log_staff
def get_app_check_name_list(staff,category,start_time,end_time):
    span=leave.application_span(start_time,end_time,staff.workshift)
    leaders=leave.get_checkLeader_list(category, staff,span)
    namelist=[]
    for leader_id in leaders:
        leader=get_or_none(StaffInfo,employee_id=leader_id)
        if leader:
            namelist.append(leader.cn_name)
        else:
            namelist.append(leader_id)
    return {'status':'success','namelist':namelist}